package org.springblade.modules.alisls;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.common.LogGroupData;
import com.aliyun.openservices.log.common.LogItem;
import com.aliyun.openservices.log.common.QueriedLog;
import com.aliyun.openservices.log.exception.LogException;
import com.aliyun.openservices.log.request.GetLogsRequest;
import com.aliyun.openservices.log.request.PutLogsRequest;
import com.aliyun.openservices.log.response.GetLogsResponse;
import com.aliyun.openservices.log.response.PutLogsResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
@Slf4j
public class AliyunSlsService {

	private final Client slsClient;
	private final AliSlsProperties aliSlsProperties;
	private final Client abroadSlsClient;


	public AliyunSlsService(AliSlsProperties aliSlsProperties) throws Exception{
		this.slsClient = new Client(aliSlsProperties.getEndpoint(), aliSlsProperties.getAccessKeyId(),aliSlsProperties.getAccessKeySecret());
		this.aliSlsProperties  = aliSlsProperties;
		this.abroadSlsClient = new Client(aliSlsProperties.getAbroadEndpoint(), aliSlsProperties.getAccessKeyId(), aliSlsProperties.getAccessKeySecret());

	}

	/**
	 * 推送单条日志到SLS
	 * @param topic 日志主题
	 * @param source 日志来源
	 * @param contents 日志内容键值对
	 */
	public void pushLog(String topic, String source, List<LogContent> contents,String logStore) throws Exception {
		List<LogItem> logItems = new ArrayList<>();
		LogItem logItem = new LogItem();
		for (LogContent content : contents) {
			logItem.PushBack(content.getKey(), content.getValue());
		}

		logItems.add(logItem);

		PutLogsRequest request = new PutLogsRequest(aliSlsProperties.getProject(), logStore, topic, source, logItems);
		PutLogsResponse putLogsResponse = slsClient.PutLogs(request);
	}

	/**
	 * 批量推送日志到SLS
	 * @param topic 日志主题
	 * @param source 日志来源
	 * @param logItems 日志项列表
	 * @param logstore logstore
	 */
	public void pushLogs(String topic, String source, List<LogItem> logItems,String logstore) throws Exception {
		PutLogsRequest request = new PutLogsRequest(aliSlsProperties.getProject(), logstore, topic, source, logItems);
		slsClient.PutLogs(request);
	}

	public static class LogContent {
		private String key;
		private String value;

		public LogContent(String key, String value) {
			this.key = key;
			this.value = value;
		}

		// getters and setters
		public String getKey() {
			return key;
		}

		public void setKey(String key) {
			this.key = key;
		}

		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}
	}


	public List<Map<String, String>> queryLogs(String logstore,String topic, String query, int from, int to) {
		List<Map<String, String>> result = new ArrayList<>();

		try {
			GetLogsRequest request = new GetLogsRequest(
				aliSlsProperties.getProject(),
				logstore,
				from,
				to,
				topic,
				query
			);

			GetLogsResponse response = slsClient.GetLogs(request);

			for (QueriedLog log : response.GetLogs()) {
				Map<String, String> logMap = new HashMap<>();
				LogItem logItem = log.GetLogItem();
				logItem.GetLogContents().forEach(content ->
					logMap.put(content.GetKey(), content.GetValue()));
				result.add(logMap);
			}
		} catch (LogException e) {
			log.error("Failed to query logs from SLS", e);
		}

		return result;
	}

	public QueriedLog getLatestLogByTopic(String logstore,String topic, int from, int to) {
		try {
			// 查询条件：按topic查询，获取最新的1条数据
			String query = "* | select * where __topic__ = '" + topic + "'  order by __time__ desc limit 1";

			GetLogsRequest request = new GetLogsRequest(aliSlsProperties.getProject(), logstore, from, to, topic, query);
			GetLogsResponse response = slsClient.GetLogs(request);
			log.info("sls获取最新的一条数据{}", JSON.toJSONString(response));
			List<QueriedLog> logs = response.getLogs();
			return logs.size()>0?logs.get(0):null;
		} catch (LogException e) {
			e.printStackTrace();
			return null;
		}
	}


	public QueriedLog getLatestLogByFields(String logstore, String topic,String fieldName,String fieldValue, int from, int to) {
		try {
			// 查询条件：按topic查询，获取最新的1条数据
//			String query = "* | select * where '" + fieldName +"' = '" + fieldValue + "'  order by __time__ desc limit 1";
			String query = fieldName +":" + fieldValue + " | select *  order by __time__ desc limit 1";
			GetLogsRequest request = new GetLogsRequest(aliSlsProperties.getProject(), logstore, from, to, topic, query);
			GetLogsResponse response = slsClient.GetLogs(request);
			log.info("sls获取最新的一条数据{}", JSON.toJSONString(response));
			List<QueriedLog> logs = response.getLogs();
			return logs.size()>0?logs.get(0):null;
		} catch (LogException e) {
			e.printStackTrace();
			return null;
		}
	}


	public List<QueriedLog> getLogsByFields(String logstore,String topic, int from, int to) {
		try {
			// 查询条件：按topic查询，获取最新的1条数据
			String query = "* | SELECT salesOrderNo as salesorderno,MAX(__time__) as latest_time WHERE LENGTH(salesOrderNo) > 0 GROUP BY salesOrderNo ORDER BY latest_time DESC limit 10";
//			String query = "* | select *  order by __time__ desc limit 20";

			GetLogsRequest request = new GetLogsRequest(aliSlsProperties.getProject(), logstore, from, to, topic, query);
			GetLogsResponse response = slsClient.GetLogs(request);
			log.info("sls获取最新的一条数据{}", JSON.toJSONString(response));
			return response.getLogs();
		} catch (LogException e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}


	public List<QueriedLog> getDeviceRunStatus(String project, String logstore,String tag, int from, int to) {

		try {
			// 查询条件：按topic查询，获取最新的1条数据
			String query = "* | select deviceid as deviceId,deviceno as deviceNo,tag,devicerunstatus as deviceRunStatus,merchantid as merchantId,time as time,exceptionremark as exceptionRemark,status as status,devicescarcestatus as deviceScarceStatus,scarceremark as scarceRemark where tag = '"+tag+"' order by __time__ desc LIMIT 1000";

			GetLogsRequest request = new GetLogsRequest(project, logstore, from, to, "", query);
			GetLogsResponse response = abroadSlsClient.GetLogs(request);
			log.info("sls获取数据{}", JSON.toJSONString(response));
			return response.getLogs();
		} catch (LogException e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}
}
